package com.demo.贪心算法;

import cn.hutool.core.lang.Console;
import lombok.AllArgsConstructor;
import lombok.ToString;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 贪心策略 会议安排
 * 一些会议需要占用会议室来进行活动，会议室不能同时容纳两场会议。给定每一个会议的开始时间和结束时间，对会议进行安排，要求在给定的时间段上能够尽量的完成更多的会议活动，如何进行安排？
 * @author cl
 */
@SuppressWarnings("all")
public class MeetingPlan {

    @Test
    public void test() {
        List<Meeting> meetings = new ArrayList<>();
        meetings.add(new Meeting("会议1", 8, 10));
        meetings.add(new Meeting("会议2", 9, 11));
        meetings.add(new Meeting("会议3", 10, 15));
        meetings.add(new Meeting("会议4", 11, 14));
        meetings.add(new Meeting("会议5", 13, 16));
        meetings.add(new Meeting("会议6", 14, 17));
        meetings.add(new Meeting("会议7", 15, 17));
        meetings.add(new Meeting("会议8", 17, 18));
        meetings.add(new Meeting("会议9", 18, 20));
        meetings.add(new Meeting("会议10", 16, 19));
        List<Meeting> meetingPlan = plan(meetings, 8, 20);
        Console.log("会议安排如下:");
        meetingPlan.forEach(System.out::println);
    }

    /**
     * 安排一场会议
     * @param meetings 所有的会议信息
     * @param start 时间段的开始时间
     * @param end 时间段的结束时间
     * @return 能够最大程度安排的会议信息
     */
    public static List<Meeting> plan(List<Meeting> meetings, Integer start, Integer end) {
        List<Meeting> result = new ArrayList<>();
        // 对会议按照结束时间进行排序
        meetings.sort(Comparator.comparingInt(m -> m.end));
        // 按结束时间依次获取会议
        for (Meeting meeting : meetings) {
            // 判断会议是否可以安排
            if (meeting.start >= start) {
                // 安排
                result.add(meeting);
                // 开始时间移动到该会议的结束时间点
                start = meeting.end;
            }
        }
        return result;
    }

    @ToString
    @AllArgsConstructor
    public static class Meeting {
        /** 会议名称 */
        public String name;
        // 会议开始时间
        public Integer start;
        // 会议结束时间
        public Integer end;
    }
}
